<template>
  <div class="image-selector-container">
    <!-- 多图模式 -->
    <template v-if="multiple">
      <div class="selected-images-list">
        <div 
          v-for="(imgUrl, index) in ((currentValue as string[]) || [])" 
          :key="index" 
          class="image-item"
          :style="{ width: parsedWidth, height: parsedHeight }"
        >
          <el-image :src="imgUrl" fit="cover" :preview-src-list="previewList(imgUrl)" :initial-index="0" :preview-teleported="true" />
          <div class="actions">
            <el-icon @click.stop="removeImage(index)" title="移除"><CircleCloseFilled /></el-icon>
          </div>
        </div>
        <div 
          class="add-image-placeholder" 
          @click="openAttachmentSelector"
          :style="{ width: parsedWidth, height: parsedHeight }"
          v-if="canAddNewImage"
        >
          <el-icon><Plus /></el-icon>
          <span style="line-height: 1;">添加图片</span>
        </div>
      </div>
    </template>
    <!-- 单图模式 -->
    <template v-else>
      <div 
        class="single-image-wrapper"
        :style="{ width: parsedWidth, height: parsedHeight }"
        @click="openAttachmentSelector"
      >
        <template v-if="currentValue && typeof currentValue === 'string'">
          <div @click.stop style="width: 100%; height: 100%;">
            <el-image :src="currentValue" fit="cover" :preview-src-list="previewList(currentValue as string)" :initial-index="0" :preview-teleported="true" />
          </div>
          <div class="actions single-actions">
            <el-icon @click.stop="clearSingleImage" title="移除"><CircleCloseFilled /></el-icon>
          </div>
        </template>
        <template v-else>
          <div class="add-image-placeholder">
            <el-icon><Camera /></el-icon>
            <span style="line-height: 1;">选择图片</span>
          </div>
        </template>
      </div>
    </template>

    <AttachmentSelectorModal
      v-if="selectorVisible"
      v-model:visible="selectorVisible"
      :multiple="multiple"
      @confirm-selection="handleConfirmSelection"
    />
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, computed, PropType, watch } from 'vue';
import { ElImage, ElIcon } from 'element-plus';
import { Plus, Camera, CircleCloseFilled } from '@element-plus/icons-vue';
import AttachmentSelectorModal from './AttachmentSelectorModal.vue';

interface AttachmentItem {
  id: number;
  file_path: string;
  file_name: string;
  url?: string;
}

export default defineComponent({
  name: 'ImageSelector',
  components: {
    ElImage,
    ElIcon,
    Plus,
    Camera,
    CircleCloseFilled,
    AttachmentSelectorModal,
  },
  props: {
    modelValue: {
      type: [String, Array] as PropType<string | string[]>,
    },
    multiple: {
      type: Boolean,
      default: false,
    },
    limit: { // For multiple mode, max number of images
        type: Number,
        default: Infinity,
    },
    width: {
      type: [String, Number],
      default: 58,
    },
    height: {
      type: [String, Number],
      default: 58,
    },
  },
  emits: ['update:modelValue'],
  setup(props, { emit }) {
    const selectorVisible = ref(false);
    const currentValue = ref<string | string[]>(props.modelValue || (props.multiple ? [] : ''));

    watch(() => props.modelValue, (newValue) => {
      if (props.multiple) {
        currentValue.value = Array.isArray(newValue) ? newValue : (newValue ? [newValue] : []);
      } else {
        currentValue.value = typeof newValue === 'string' ? newValue : '';
      }
    }, { immediate: true, deep: true });


    const parsedWidth = computed(() => {
      return typeof props.width === 'number' ? `${props.width}px` : props.width;
    });

    const parsedHeight = computed(() => {
      return typeof props.height === 'number' ? `${props.height}px` : props.height;
    });
    
    const canAddNewImage = computed(() => {
        if (!props.multiple) return false; 
        return ((currentValue.value as string[])?.length || 0) < props.limit;
    });

    const openAttachmentSelector = () => {
      if (props.multiple && !canAddNewImage.value && ((currentValue.value as string[])?.length || 0) > 0 ) {
        return;
      }
      selectorVisible.value = true;
    };

    const handleConfirmSelection = (selectedItems: AttachmentItem[]) => {
      console.log(selectedItems)
      selectorVisible.value = false;
      if (!selectedItems || selectedItems.length === 0) return;

      const selectedUrls = selectedItems.map(item => item.url || item.file_path);

      if (props.multiple) {
        let newValues = [...(Array.isArray(currentValue.value) ? currentValue.value : [])];
        newValues.push(...selectedUrls);
        if (newValues.length > props.limit) {
            newValues = newValues.slice(0, props.limit);
        }
        currentValue.value = newValues;
        emit('update:modelValue', newValues);
      } else {
        currentValue.value = selectedUrls[0] || '';
        emit('update:modelValue', selectedUrls[0] || '');
      }
    };

    const removeImage = (index: number) => {
      if (props.multiple && Array.isArray(currentValue.value)) {
        const newValues = [...currentValue.value];
        newValues.splice(index, 1);
        currentValue.value = newValues;
        emit('update:modelValue', newValues);
      }
    };
    
    const clearSingleImage = () => {
        if(!props.multiple) {
            currentValue.value = '';
            emit('update:modelValue', '');
        }
    };

    const previewList = (url: string) => {
        if (props.multiple && Array.isArray(currentValue.value)) {
            return currentValue.value;
        }
        return url ? [url] : [];
    };

    return {
      selectorVisible,
      currentValue,
      parsedWidth,
      parsedHeight,
      openAttachmentSelector,
      handleConfirmSelection,
      removeImage,
      clearSingleImage,
      canAddNewImage,
      previewList,
    };
  },
});
</script>

<style lang="less" scoped>
.image-selector-container {
  display: inline-block; 
}

.selected-images-list {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.image-item,
.add-image-placeholder,
.single-image-wrapper {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  background-color: #fafafa;

  &:hover {
    border-color: var(--el-color-primary);
  }

  .el-image {
    width: 100%;
    height: 100%;
  }
}

.add-image-placeholder {
  flex-direction: column;
  color: var(--el-text-color-placeholder);
  .el-icon {
    font-size: 20px;
    margin-bottom: 4px;
  }
  span {
    font-size: 12px;
  }
}

.image-item .actions {
  position: absolute;
  top: 2px;
  right: 2px;
  background-color: rgba(0, 0, 0, 0.3);
  border-radius: 50%;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 2px;

  .el-icon {
    color: white;
    font-size: 14px;
  }
}
.single-image-wrapper .actions.single-actions {
  position: absolute;
  top: 2px;
  right: 2px;
  background-color: rgba(0, 0, 0, 0.3);
  border-radius: 50%;
  padding: 2px;
  display: none;
  align-items: center;
  justify-content: center;

  .el-icon {
    color: white;
    font-size: 14px;
  }
}

.image-item:hover .actions,
.single-image-wrapper:hover .actions.single-actions {
  display: flex;
}

// Fix for double border in single image mode placeholder
.single-image-wrapper .add-image-placeholder {
  border: none;
}
</style> 